[toc]
kubeadm 专题 一 init 究竟干了些什么
kubeadm 所在层次
kubeadm 属于第二层,用于管理集群。
kubeadm init 的流程(phase)介绍
phase 阶段
preflight 预置检查
kubelet-start 生成 kubelet 配置,并重启kubelet
certs 生成认证
/etcd-ca 生成自签名CA以为etcd配置标识
/apiserver-etcd-client 生成apiserver用于访问etcd的证书
/etcd-healthcheck-client 生成liveness探针使用的证书,用于检查etcd 的 healtcheck 状态
/etcd-server 生成 etcd 服务使用的的证书
/etcd-peer 为etcd节点生成证书以相互通信
/ca 生成自签名的 Kubernetes CA,为其他 Kubernetes 组件预配标识
/apiserver 生成用于提供 Kubernetes API 的证书 api server端证书
/apiserver-kubelet-client 为 API 服务器生成证书以连接到 kubelet
/front-proxy-ca 生成自签名 CA 以预配front proxy 标识
/front-proxy-client 为前端代理客户端生成证书
/sa 生成用于对服务帐户令牌及其公钥进行签名的私钥
kubeconfig 生成 control plane 和 admin 管理员相关的kubeconfig 文件
/admin 生成admin 管理员和kubeadm 自身使用的kubeconfig文件
/kubelet 生成kebelet使用的,仅用于引导集群(bootstrap)的kubeconfig 文件
/controller-manager 生成 controller manager 使用的kubeconfig文件
/scheduler 生成 scheduler 使用的kubeconfig文件
kubelet-start 生成kubelet的环境变量文件/var/lib/kubelet/kubeadm-flags.env 和 配置信息文件 /var/lib/kubelet/config.yaml,然后 启动/重启 kubelet(systemd 模式)
control-plane 生成拉起 control plane(master)static Pod 的 manifest 文件
/apiserver 生成拉起 kube-apiserver 的 static Pod manifest
/controller-manager 生成拉起 kube-controller-manager 的static Pod manifest
/scheduler 生成拉起 kube-scheduler 的 static Pod manifest
etcd 生成本地 ETCD的 static Pod manifest 文件
/local 生成单节点本地 ETCD static Pod manifest 文件
upload-config 上传kubeadm和kubelet配置为 ConfigMap
/kubeadm 上传 kubeadm ClusterConfiguration 为 ConfigMap
/kubelet 上传 kubelet component config 为 ConfigMap
upload-certs 上传证书到 kubeadm-certs
mark-control-plane 标识节点为 control-plane
bootstrap-token 生成 bootstrap tokens 用于其他节点加入集群
addon 安装所需的插件以通过一致性测试
/coredns 安装 CoreDNS 插件
/kube-proxy 安装 kube-proxy 插件
kubeadm 命令行参数
命令用法
kubeadm init [flags]
参数说明
--apiserver-advertise-address string 设置 apiserver 绑定的 IP.
--apiserver-bind-port int32 设置apiserver 监听的端口. (默认 6443)
--apiserver-cert-extra-sans strings api证书中指定额外的Subject Alternative Names (SANs) 可以是IP 也可以是DNS名称。 证书是和SAN绑定的。
--cert-dir string 证书存放的目录 (默认 "/etc/kubernetes/pki")
--certificate-key string kubeadm-cert secret 中 用于加密 control-plane 证书的key
--config string kubeadm 配置文件的路径.
--cri-socket string CRI socket 文件路径,如果为空 kubeadm 将自动发现相关的socket文件; 只有当机器中存在多个 CRI socket 或者 存在非标准 CRI socket 时才指定.
--dry-run 测试,并不真正执行;输出运行后的结果.
--feature-gates string 指定启用哪些额外的feature 使用 key=value 对的形式。
--help 帮助文档
--ignore-preflight-errors strings 忽略前置检查错误,被忽略的错误将被显示为警告. 例子: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.
--image-repository string 选择拉取 control plane images 的镜像repo (default "k8s.gcr.io")
--kubernetes-version string 选择K8S版本. (default "stable-1")
--node-name string 指定node的名称,默认使用 node 的 hostname.
--pod-network-cidr string 指定 pod 的网络, control plane 会自动将 网络发布到其他节点的node,让其上启动的容器使用此网络
--service-cidr string 指定service 的IP 范围. (default "10.96.0.0/12")
--service-dns-domain string 指定 service 的 dns 后缀, e.g. "myorg.internal". (default "cluster.local")
--skip-certificate-key-print 不打印 control-plane 用于加密证书的key.
--skip-phases strings 跳过指定的阶段(phase)
--skip-token-print 不打印 kubeadm init 生成的 default bootstrap token
--token string 指定 node 和control plane 之间,简历双向认证的token ,格式为 [a-z0-9]{6}\.[a-z0-9]{16} - e.g. abcdef.0123456789abcdef
--token-ttl duration token 自动删除的时间间隔。 (e.g. 1s, 2m, 3h). 如果设置为 '0', token 永不过期 (default 24h0m0s)
--upload-certs 上传 control-plane 证书到 kubeadm-certs Secret.
init 工作流
kubeadm init通过执行以下步骤来引导Kubernetes控制平面节点:
1.在进行更改之前运行一系列飞行前检查以验证系统状态。某些检查仅触发警告,其他检查被视为错误,并将退出kubeadm,直到问题得到纠正或用户指定 --ignore-preflight-errors = <list-of-errors>
来忽略错误。
2.生成自签名 CA(或使用现有CA),以便为群集中的每个组件设置标识。如果用户通过将其放在通过--cert-dir配置的cert目录(默认情况下为/etc/kubernetes/pki
)中提供了自己的CA证书和/或密钥,则会跳过此步骤,如使用自定义证书文档中所述。 APIServer证书将 --apiserver-cert-extra-sans
参数提供的额外SAN条目添加到证书信息中,如果需要,可以小写。
3.在 /etc/kubernetes/
中为 kubelet, controller-manager和scheduler 写入kubeconfig文件,用于连接到API服务器,每个都有自己的标识,以及另一个名为 admin.conf
的管理员kubeconfig文件。
4.生成启动 kubelet 服务所需的配置文件和环境变量,并启动kubelet (systemd 方式)生成文件如下
- /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf 环境变量
- /etc/kubernetes/bootstrap-kubelet.conf/
- /etc/kubernetes/kubelet.conf
- /var/lib/kubelet/config.yaml
- /var/lib/kubelet/kubeadm-flags.env 环境变量
kubelet 使用4个文件的方式如下
$ systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; disabled; vendor preset: disabled)
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since Sun 2019-08-18 14:16:37 CST; 13min ago
Docs: https://kubernetes.io/docs/
Main PID: 14980 (kubelet)
CGroup: /system.slice/kubelet.service
└─14980 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml
1.为apiserver,control-manager 和scheduler 生成静态Pod清单。
如果未提供外部etcd,则会为etcd生成其他静态Pod清单。 Static Pod清单写入/etc/kubernetes/manifests
; kubelet监视此目录以便Pods在启动时创建。
control plane 的pod 启动后,init 开始继续执行后面的流程。
2.将标签和污点应用于控制平面节点,以便不会在那里运行其他工作负载。
3.生成其他节点将来可用于向控件平面注册自己的令牌。或者,用户可以通过--token
参数来指定一个令牌。,具体在 kubeadm token 文档中.
4.进行所有必要的配置,以允许其他节点通过引导令牌 bootstrap token 和 TLS boostrap 机制进行加入
- 写入加入集群的所需的信息到configmap, 设置相关的RBAC 规则。
- 让bootstrap token 访问 CSR
(证书签名请求)
签名 API - Configure auto-approval for new CSR requests. 对CSR 请求
(证书签名请求)
配置自动同意。
通过 API server 安装 DNS 服务器 (CoreDNS) 和 kube-proxy 组件。在 Kubernetes 版本 1.11 和更高版本中,CoreDNS 是默认 DNS 服务器。要安装 kube-dns 而不是 CoreDNS,必须在 kubeadm 配置文件的ClusterConfiguration 字段中配置 DNS 附加组件(通过 kubeadm config 文件)。请注意,虽然已部署 DNS 服务器,但安装 CNI 前该POD 不会被调度到节点(可以理解为不回被实际部署,或不会生效)。
kubeadm init phase 的用法
查看 kubeadm init phase 列表
$ kubeadm init phase
Use this command to invoke single phase of the init workflow
Usage:
kubeadm init phase [command]
Available Commands:
addon Install required addons for passing Conformance tests
bootstrap-token Generates bootstrap tokens used to join a node to a cluster
certs Certificate generation
control-plane Generate all static Pod manifest files necessary to establish the control plane
etcd Generate static Pod manifest file for local etcd
kubeconfig Generate all kubeconfig files necessary to establish the control plane and the admin kubeconfig file
kubelet-start Write kubelet settings and (re)start the kubelet
mark-control-plane Mark a node as a control-plane
preflight Run pre-flight checks
upload-certs Upload certificates to kubeadm-certs
upload-config Upload the kubeadm and kubelet configuration to a ConfigMap
可以查看某个具体的phase下的子phase 列表
$ kubeadm init phase control-plane --help
This command is not meant to be run on its own. See list of available subcommands.
Usage:
kubeadm init phase control-plane [flags]
kubeadm init phase control-plane [command]
Available Commands: #下面的就是子phase
all Generate all static Pod manifest files
apiserver Generates the kube-apiserver static Pod manifest
controller-manager Generates the kube-controller-manager static Pod manifest
scheduler Generates the kube-scheduler static Pod manifest
查看 control-plane phase 下 controller-manager 子 phase 的用法详情
$ kubeadm init phase control-plane controller-manager --help
Generates the kube-controller-manager static Pod manifest
Usage:
kubeadm init phase control-plane controller-manager [flags]
Flags:
--cert-dir string The path where to save and store the certificates. (default "/etc/kubernetes/pki")
--config string Path to a kubeadm configuration file.
--controller-manager-extra-args mapStringString A set of extra flags to pass to the Controller Manager or override default ones in form of <flagname>=<value>
-h, --help help for controller-manager
--image-repository string Choose a container registry to pull control plane images from (default "k8s.gcr.io")
--kubernetes-version string Choose a specific Kubernetes version for the control plane. (default "stable-1")
--pod-network-cidr string Specify range of IP addresses for the pod network. If set, the control plane will automatically allocate CIDRs for every node.
执行某个 phase 或者跳过某个 phase
sudo kubeadm init phase control-plane all --config=configfile.yaml
sudo kubeadm init phase etcd local --config=configfile.yaml
# you can now modify the control plane and etcd manifest files
sudo kubeadm init --skip-phases=control-plane,etcd --config=configfile.yaml
kubeadm config 文件
注意,这个 config 文件特性在1.15 中依然是 beta,在将来可能改变
查看 kubeadm config print的帮助
[root@rancher ~]# kubeadm config print -h
This command prints configurations for subcommands provided.
Usage:
kubeadm config print [flags]
kubeadm config print [command]
Available Commands:
init-defaults Print default init configuration, that can be used for 'kubeadm init'
join-defaults Print default join configuration, that can be used for 'kubeadm join'
打印默认的init 配置文件
kubeadm config print init-defaults > initconfig.yaml
打开 initconfig, 内容如下
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 1.2.3.4
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: rancher.local
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.14.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
scheduler: {}
上面的内容只包含额了最简话的InitConfiguration type 的内容,kubeadm 完整的内容包含5大部分,如下,每个type 之间,需要用yaml的 ---
文档隔离进行分离。
init-full-config.yaml 文件结构
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: JoinConfiguration
想细的内容可以参阅kubeadm api,kube-proxy配置部分的内容细节在这里KubeProxyConfiguration 比如我要修改kube-proxy的模式为IPVS 那么修改后的init-full-config.yaml 内容为如下
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs" 修改在这里
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: JoinConfiguration
关于如何通过kubeadm 配置启用 IPVS 请参阅 关于如何定制化 control plane 请参阅